﻿using System;
using System.Collections.Generic;
using UBlockly.Compotent;
using UnityEngine;
using UnityEngine.EventSystems;

namespace UBlockly
{
    using UBlockly.UI;
    using Scriptable;

    public class BlockExtralHandler
    {
        /// <summary>
        /// node被添加到工作区
        /// </summary>
        public Action<int,BlockObject> NodeAddToSpaceHandler = null;
        /// <summary>
        /// （侧栏）node被拖拽事件
        /// </summary>
        public Action<int, PointerEventData, BlockObject,bool> NodeBeginDragHandler = null;
        /// <summary>
        /// （侧栏）node被点击
        /// </summary>
        public Action<int,PointerEventData, BlockObject,bool> NodeClickHandler = null;
        /// <summary>
        /// （侧栏）node拖动ing
        /// </summary>
        public Action<int, PointerEventData, BlockObject,bool> NodeDragHandler = null;
        /// <summary>
        /// （侧栏）node被drop到工作区
        /// </summary>
        public Action<int,PointerEventData, BlockObject,bool> NodeDropSpaceHandler = null;
        /// <summary>
        /// （侧栏）node被drop到侧栏
        /// </summary>
        public Action<int,PointerEventData, BlockObject,bool> NodeDropSideBarHandler = null;
        /// <summary>
        /// （侧栏）node进入侧栏区间
        /// </summary>
        public Action<int,PointerEventData, BlockObject,bool> NodeEnterSideBarHandler = null;
        /// <summary>
        /// （侧栏）node离开侧栏区间
        /// </summary>
        public Action<int,PointerEventData, BlockObject,bool> NodeExitSideBarHandler = null;
        /// <summary>
        /// node参数被选中
        /// </summary>
        public Action<IParamGetterCompotent> NodeParamSelectHandler = null;
        /// <summary>
        /// node参数取消选中
        /// </summary>
        public Action<IParamGetterCompotent> NodeParamDeselectHandler = null;
        /// <summary>
        /// node开始执行
        /// </summary>
        public Action<int,BlockObject> NodeBeginExcute = null;
        /// <summary>
        /// node执行完毕
        /// </summary>
        public Action<int,BlockObject> NodeEndExcute = null;
        /// <summary>
        /// node嵌套操作
        /// </summary>
        public Action<int,BlockObject> PackNodeHandler = null;
        /// <summary>
        /// node衔接操作
        /// </summary>
        public Action<int,BlockObject> SlotNodeHandler = null;  
    }

    /// <summary>
    /// Node回调事件
    /// </summary>
    internal class NodeHandlerSystem
    {
        private UBlockEntry blockEntry;
        private int blockEntryHashCode;
        private BlockExtralHandler extralHandler;

        public NodeHandlerSystem(UBlockEntry entry,BlockExtralHandler hanlder)
        {
            blockEntry = entry;
            extralHandler = hanlder;
            blockEntryHashCode = entry.EntryHash;
        }

        public void NodeAddToSpaceHandler(BlockObject blockObject)
        {
            extralHandler.NodeAddToSpaceHandler?.Invoke(blockEntryHashCode, blockObject);
        }

        public void NodeBeginDragHandler(PointerEventData eventData, BlockObject blockObject, bool isSide)
        {
            extralHandler.NodeBeginDragHandler?.Invoke(blockEntryHashCode,eventData,blockObject,isSide);
        }

        public void NodeClickHandler(PointerEventData eventData, BlockObject blockObject, bool isSide)
        {
            extralHandler.NodeClickHandler?.Invoke(blockEntryHashCode, eventData, blockObject, isSide);
        }

        public void NodeDragHandler(PointerEventData eventData, BlockObject blockObject, bool isSide)
        {
            extralHandler.NodeDragHandler?.Invoke(blockEntryHashCode, eventData, blockObject, isSide);
        }

        public void NodeDropSpaceHandler(PointerEventData eventData, BlockObject blockObject, bool isSide)
        {
            extralHandler.NodeDropSpaceHandler?.Invoke(blockEntryHashCode, eventData, blockObject, isSide);
        }

        public void NodeDropSideBarHandler(PointerEventData eventData, BlockObject blockObject, bool isSide)
        {
            extralHandler.NodeDropSideBarHandler?.Invoke(blockEntryHashCode, eventData, blockObject, isSide);
        }

        public void NodeEnterSideBarHandler(PointerEventData eventData, BlockObject blockObject, bool isSide)
        {
            extralHandler.NodeEnterSideBarHandler?.Invoke(blockEntryHashCode, eventData, blockObject, isSide);
        }

        public void NodeExitSideBarHandler(PointerEventData eventData, BlockObject blockObject, bool isSide)
        {
            extralHandler.NodeExitSideBarHandler?.Invoke(blockEntryHashCode,eventData,blockObject,isSide);
        }

        public void NodeParamSelectHandler(IParamGetterCompotent paramObj)
        {
            var panel = BlockFramework.BlockTipPanel.OpenSetterPanel(paramObj.ValueType);
            if (panel != null)
            {
                extralHandler.NodeParamSelectHandler?.Invoke(paramObj);
                panel.ParamSetter = obj =>
                {
                    paramObj.SetDisplayValue(obj.displayValue);
                    paramObj.SetVarObjectValue(obj.typeValue);
                    panel.Close();
                };
            }
        }

        public void NodeParamDeselectHandler(IParamGetterCompotent paramObj)
        {
            extralHandler.NodeParamDeselectHandler?.Invoke(paramObj);
        }

        public void NodeBeginExcute(BlockObject blockObject)
        {
            extralHandler.NodeBeginExcute?.Invoke(blockEntryHashCode,blockObject);
        }

        public void NodeEndExcute(BlockObject blockObject)
        {
            extralHandler.NodeEndExcute?.Invoke(blockEntryHashCode,blockObject);
        }

        public void PackNodeHandler(BlockObject blockObject)
        {
            extralHandler.PackNodeHandler?.Invoke(blockEntryHashCode,blockObject);
            Debug.LogError("pack");
            BlockFramework.Sound.PlayClip(BlockSound.PackAudio);
        }

        public void DepackNodeHandler(BlockObject blockObject)
        {
            Debug.LogError("depack");
            BlockFramework.Sound.PlayClip(BlockSound.DepackAudio);
        }

        public void SlotNodeHandler(BlockObject blockObject)
        {
            extralHandler.SlotNodeHandler?.Invoke(blockEntryHashCode, blockObject);
            Debug.LogError("slot");
            BlockFramework.Sound.PlayClip(BlockSound.SlotAudio);
        }

        public void DeslotNodeHandler(BlockObject blockObject)
        {
            Debug.LogError("deslot");
            BlockFramework.Sound.PlayClip(BlockSound.DeslotAudio);
        }
    }
}
